package com.chuantou.yuba.ui.fragment;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v7.widget.RecyclerView;
import android.text.InputFilter;
import android.text.InputFilter.LengthFilter;
import android.text.InputType;
import android.text.TextUtils;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.android.volley.Request.Method;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.NetworkImageView;
import com.chuantou.yuba.R;
import com.chuantou.yuba.api.RequestManager;
import com.chuantou.yuba.api.UriHelper;
import com.chuantou.yuba.api.request.MultiPartRequest;
import com.chuantou.yuba.api.to.BaseTO;
import com.chuantou.yuba.api.to.CityListTO;
import com.chuantou.yuba.api.to.CityTO;
import com.chuantou.yuba.api.to.IdNameTO;
import com.chuantou.yuba.api.to.ImageTO;
import com.chuantou.yuba.api.to.UserTO;
import com.chuantou.yuba.ui.LoginActivity;
import com.chuantou.yuba.util.AccountManager;
import com.chuantou.yuba.util.BitmapBinder;
import com.chuantou.yuba.util.FileUtil;
import com.chuantou.yuba.util.MediaUtil;
import com.chuantou.yuba.util.UiUtil;
import com.chuantou.yuba.util.ViewHolder;
import com.google.gson.Gson;

public abstract class AbsPublishNearFishingFragment extends BaseFragment implements OnClickListener {
	// 允许选择的最大图片数量
	private static final int MAX_PIC_NUMBER = 5;
	private static final int MENU_ITEM_ID_GALLERY = 0;
	private static final int MENU_ITEM_ID_CAPTURE = 1;
	private static final int REQUEST_CODE_CAPTURE = 20000;
	private static final int REQUEST_CODE_GALLERY = 20001;
	protected static final int REQUEST_CODE_ADDRESS = 20002;
	public static final File CACHE_DIR = FileUtil.getImageCacheDir();
	private List<CityTO> mCities;
	private String mCapturePath = null;
	protected ImageAdapter mImageAdapter;
	protected List<ImageTO> mDeleteImages = new ArrayList<ImageTO>();

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mImageAdapter = new ImageAdapter();
		CityListTO list = parseLocalCity();
		if (list != null) {
			mCities = list.getCities();
		}
	}

	private CityListTO parseLocalCity() {
		try {
			InputStream in = mContext.getAssets().open("cities");
			BufferedReader reader = new BufferedReader(new InputStreamReader(in));
			String str = reader.readLine();
			Gson gson = new Gson();
			return gson.fromJson(str, CityListTO.class);
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}

	protected void showProvinceDialog() {
		AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
		builder.setTitle(R.string.choose_district);
		builder.setAdapter(new BaseAdapter() {

			@Override
			public View getView(int position, View convertView, ViewGroup parent) {
				if (convertView == null) {
					convertView = View.inflate(mContext, R.layout.city, null);
				}
				CityTO city = mCities.get(position);
				TextView cityView = ViewHolder.get(convertView, R.id.city);
				cityView.setText(city.getName());
				return convertView;
			}

			@Override
			public long getItemId(int position) {
				return position;
			}

			@Override
			public Object getItem(int position) {
				return mCities == null ? null : mCities.get(position);
			}

			@Override
			public int getCount() {
				return mCities == null ? 0 : mCities.size();
			}

		}, new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				CityTO cityTO = mCities.get(which);
				showCityDialog(cityTO);
			}
		});
		builder.create().show();
	}

	private void showCityDialog(final CityTO province) {
		final List<CityTO> cities = province.getCities();
		AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
		builder.setTitle(province.getName());
		builder.setAdapter(new BaseAdapter() {

			@Override
			public View getView(int position, View convertView, ViewGroup parent) {
				if (convertView == null) {
					convertView = View.inflate(mContext, R.layout.city, null);
				}
				CityTO city = cities.get(position);
				TextView cityView = ViewHolder.get(convertView, R.id.city);
				cityView.setText(city.getName());
				return convertView;
			}

			@Override
			public long getItemId(int position) {
				return position;
			}

			@Override
			public Object getItem(int position) {
				return cities == null ? null : cities.get(position);
			}

			@Override
			public int getCount() {
				return cities == null ? 0 : cities.size();
			}

		}, new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				CityTO city = cities.get(which);
				onCityPicked(province, city);
			}
		});
		builder.create().show();
	}

	protected void showInputAddressDialog(final InputListener listener) {
		AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
		builder.setTitle(R.string.input_address_title);
		View view = View.inflate(mContext, R.layout.input_view, null);
		final EditText inputView = (EditText) view.findViewById(R.id.input);
		InputFilter[] filters = { new LengthFilter(50) };
		inputView.setFilters(filters);
		builder.setView(view);
		builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				if (listener != null) {
					listener.onFishingInput(inputView.getText().toString().trim());
				}
			}

		});
		builder.create().show();
	}

	protected void showInputContactDialog(final InputListener listener) {
		AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
		builder.setTitle(R.string.input_contact_title);
		View view = View.inflate(mContext, R.layout.input_view, null);
		final EditText inputView = (EditText) view.findViewById(R.id.input);
		InputFilter[] filters = { new LengthFilter(10) };
		inputView.setFilters(filters);
		builder.setView(view);
		builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				if (listener != null) {
					listener.onFishingInput(inputView.getText().toString().trim());
				}
			}

		});
		builder.create().show();
	}

	protected void showNormalTextDialog(String title, int maxLength, final InputListener listener) {
		AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
		builder.setTitle(title);
		View view = View.inflate(mContext, R.layout.input_view, null);
		final EditText inputView = (EditText) view.findViewById(R.id.input);
		InputFilter[] filters = { new LengthFilter(maxLength) };
		inputView.setFilters(filters);
		builder.setView(view);
		builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				if (listener != null) {
					listener.onFishingInput(inputView.getText().toString().trim());
				}
			}

		});
		builder.create().show();
	}

	protected void showInputPhoneDialog(final InputListener listener) {
		AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
		builder.setTitle(R.string.input_phone_title);
		View view = View.inflate(mContext, R.layout.input_view, null);
		final EditText inputView = (EditText) view.findViewById(R.id.input);
		InputFilter[] filters = { new LengthFilter(30) };
		inputView.setFilters(filters);
		inputView.setInputType(InputType.TYPE_CLASS_PHONE);
		builder.setView(view);
		builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				if (listener != null) {
					listener.onFishingInput(inputView.getText().toString().trim());
				}
			}
		});
		builder.create().show();
	}

	protected void showMenuListDialog(final List<IdNameTO> list, DialogInterface.OnClickListener listener) {
		AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
		builder.setAdapter(new BaseAdapter() {

			@Override
			public View getView(int position, View convertView, ViewGroup parent) {
				if (convertView == null) {
					convertView = View.inflate(mContext, R.layout.menu_item, null);
				}
				IdNameTO to = list.get(position);
				TextView textView = ViewHolder.get(convertView, R.id.text);
				textView.setText(to.getName());
				return convertView;
			}

			@Override
			public long getItemId(int position) {
				return position;
			}

			@Override
			public Object getItem(int position) {
				return list == null ? null : list.get(position);
			}

			@Override
			public int getCount() {
				return list == null ? 0 : list.size();
			}

		}, listener);
		builder.create().show();
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
		switch (v.getId()) {
		case R.id.image:
			menu.add(0, MENU_ITEM_ID_GALLERY, 0, R.string.title_btn_localphoto);
			menu.add(0, MENU_ITEM_ID_CAPTURE, 0, R.string.title_btn_takephoto);
			break;
		default:
			break;
		}
		super.onCreateContextMenu(menu, v, menuInfo);
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case MENU_ITEM_ID_GALLERY:
			startImageLocalPickActivity();
			break;
		case MENU_ITEM_ID_CAPTURE:
			startImageCaptureActivity();
			break;
		default:
			break;
		}
		return super.onContextItemSelected(item);
	}

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (resultCode == Activity.RESULT_CANCELED) {
			// 删除拍照的原图;
			if (mCapturePath != null) {
				new File(mCapturePath).delete();
				mCapturePath = null;
			}
			return;
		}
		// 根据上面发送过去的请求码来区别
		switch (requestCode) {
		case REQUEST_CODE_CAPTURE: // take photo;
		{
			String path = Uri.fromFile(new File(mCapturePath)).toString();
			ImageTO image = new ImageTO();
			image.setUrl(path);
			setCoverView(image);
			mCapturePath = null;
		}
			break;
		case REQUEST_CODE_GALLERY: // local photo;
		{
			Uri selectedImage = data.getData();
			String path = MediaUtil.getPath(mContext, selectedImage);
			path = Uri.fromFile(new File(path)).toString();
			ImageTO image = new ImageTO();
			image.setUrl(path);
			setCoverView(image);
		}
			break;
		default:
			break;
		}

	}

	protected void setCoverView(ImageTO image) {
		mImageAdapter.add(image);
		mImageAdapter.notifyDataSetChanged();
	}

	protected void setCoverView(List<ImageTO> images) {
		mImageAdapter.add(images);
		mImageAdapter.notifyDataSetChanged();
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.image:
			v.showContextMenu();
			break;
		case R.id.delete: {
			Object tag = v.getTag();
			if (tag != null && tag instanceof ImageTO) {
				ImageTO image = (ImageTO) tag;
				mImageAdapter.remove(image);
				mImageAdapter.notifyDataSetChanged();
				mDeleteImages.add(image);
			}
		}
			break;
		default:
			break;
		}
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
	}

	protected void showUploadSuccessDialog() {
		AlertDialog.Builder builder = new Builder(getActivity());
		builder.setTitle(R.string.upload_success);
		builder.setMessage(R.string.near_fishing_upload_tip);
		builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
				getActivity().finish();
			}
		});
		builder.create().show();
	}

	private void startImageCaptureActivity() {
		Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
		String fileName = String.format("%d.jpg", System.currentTimeMillis());
		File file = new File(CACHE_DIR, fileName);
		mCapturePath = file.getAbsolutePath();
		intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
		startActivityForResult(intent, REQUEST_CODE_CAPTURE);
	}

	private void startImageLocalPickActivity() {
		Intent i = new Intent(Intent.ACTION_GET_CONTENT).setType("image/*");
		startActivityForResult(i, REQUEST_CODE_GALLERY);
	}

	public abstract void onSubmit();

	public abstract void onCityPicked(CityTO province, CityTO city);

	public int getMaxPic() {
		return MAX_PIC_NUMBER;
	}

	interface InputListener {
		void onFishingInput(String input);
	}

	protected void uploadFishingShop(long shopId, int type, String provinceId, String cityId, String name, String content, String contact, String phone,
			String address, String shopUrl) {
		AccountManager accountManager = AccountManager.getInstance(mContext);
		if (!accountManager.isLogined()) {
			UiUtil.showNoLoginDialog(this, -1, LoginActivity.ACTION_RETURN);
			return;
		}
		final UserTO user = accountManager.getUserTO();
		if (user.isExpired()) {
			Toast.makeText(mContext, R.string.message_token_expired, Toast.LENGTH_SHORT).show();
			LoginActivity.start(this, -1, LoginActivity.ACTION_RETURN);
			return;
		}
		final ProgressDialog dialog = new ProgressDialog(getActivity());
		dialog.setMessage(getString(R.string.uploading_fishing));
		dialog.setCancelable(false);
		dialog.show();
		String url = UriHelper.getAddFishingShopUrl();
		MultiPartRequest<BaseTO> request = new MultiPartRequest<BaseTO>(Method.POST, url, new Listener<BaseTO>() {

			@Override
			public void onResponse(BaseTO response) {
				if (getActivity() != null) {
					if (dialog != null && dialog.isShowing()) {
						dialog.dismiss();
					}
					if (response != null) {
						if (response.isSuccess()) {
							showUploadSuccessDialog();
						} else {
							if (response.getStatus() == BaseTO.STATUS_TOKEN_ERROR || response.getStatus() == BaseTO.STATUS_TOKEN_EXPIRED) {
								Toast.makeText(mContext, R.string.message_token_expired, Toast.LENGTH_SHORT).show();
								LoginActivity.start(getActivity(), -1, LoginActivity.ACTION_RETURN);
							} else {
								String msg = response.getMsg();
								msg = TextUtils.isEmpty(msg) ? getString(R.string.upload_failed) : msg;
								Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
							}
						}
					} else {
						Toast.makeText(mContext, R.string.upload_failed, Toast.LENGTH_SHORT).show();
					}
				}
			}
		}, new ErrorListener() {

			@Override
			public void onErrorResponse(VolleyError error) {
				if (getActivity() != null) {
					if (dialog != null && dialog.isShowing()) {
						dialog.dismiss();
					}
					Toast.makeText(mContext, R.string.request_error, Toast.LENGTH_SHORT).show();
				}
			}
		}, BaseTO.class);
		request.addStringUpload(UriHelper.PARAMS_UID, String.valueOf(user.getUid()));
		request.addStringUpload(UriHelper.PARAMS_TOKEN, user.getToken());
		request.addStringUpload(UriHelper.PARAMS_TYPE, String.valueOf(type));
		request.addStringUpload(UriHelper.PARAMS_NAME, name);
		request.addStringUpload(UriHelper.PARAMS_CONTENT, content);
		request.addStringUpload(UriHelper.PARAMS_CONTACT, contact);
		request.addStringUpload(UriHelper.PARAMS_PHONE, phone);
		request.addStringUpload(UriHelper.PARAMS_ADDRESS, address);
		if (!TextUtils.isEmpty(shopUrl)) {
			request.addStringUpload(UriHelper.PARAMS_SHOP_URL, shopUrl);
		}
		if (!TextUtils.isEmpty(provinceId)) {
			request.addStringUpload(UriHelper.PARAMS_STATE_ID, provinceId);
		}
		if (!TextUtils.isEmpty(cityId)) {
			request.addStringUpload(UriHelper.PARAMS_CITY_ID, cityId);
		}
		if (shopId > 0) {
			request.addStringUpload(UriHelper.PARAMS_ID, String.valueOf(shopId));
		}
		List<ImageTO> images = mImageAdapter.getImages();
		int counter = 1;
		if (images != null && !images.isEmpty()) {
			for (ImageTO image : images) {
				if (image.getId() <= 0) {
					String path = Uri.parse(image.getUrl()).getPath();
					File file = new File(path);
					if (file.exists()) {
						request.addFileUpload("picture" + counter, file);
						counter++;
					}
				}
			}
		}
		List<Long> idList = new ArrayList<Long>();
		for (ImageTO image : mDeleteImages) {
			if (image.getId() > 0) {
				idList.add(image.getId());
			}
		}
		int size = idList.size();
		StringBuffer buffer = new StringBuffer();
		for (int i = 0; i < size; i++) {
			buffer.append(idList.get(i));
			if (i != size - 1) {
				buffer.append(",");
			}
		}
		String ids = buffer.toString();
		if (!TextUtils.isEmpty(ids)) {
			ids = ids.substring(0, ids.length());
			request.addStringUpload(UriHelper.PARAMS_DEL_PHOTOS, ids);
		}
		RequestManager.startUpload(mContext, request);
	}

	class ImageAdapter extends RecyclerView.Adapter<ImageHolder> {
		private List<ImageTO> mImages = new ArrayList<ImageTO>();
		private int mMaxPic = getMaxPic();

		public List<ImageTO> getImages() {
			return mImages;
		}

		@Override
		public int getItemCount() {
			if (mImages.size() < mMaxPic) {
				return mImages.size() + 1;
			}
			return mMaxPic;
		}

		public void add(ImageTO image) {
			mImages.add(image);
		}

		public void add(List<ImageTO> images) {
			mImages.addAll(images);
		}

		public void remove(ImageTO image) {
			mImages.remove(image);
		}

		@Override
		public void onBindViewHolder(ImageHolder holder, int position) {
			NetworkImageView imageView = holder.getImageView();
			if (position < mImages.size()) {
				ImageTO image = mImages.get(position);
				String path = image.getUrl();
				BitmapBinder.bindNetImage(mContext, imageView, path, R.drawable.default_cover, false);
				imageView.setOnClickListener(null);
				holder.getDeleteImageView().setVisibility(View.VISIBLE);
				holder.getDeleteImageView().setTag(image);
			} else {
				imageView.clear();
				BitmapBinder.bindNetImage(mContext, imageView, null, R.drawable.image_add, false);
				holder.getDeleteImageView().setVisibility(View.INVISIBLE);
				imageView.setOnClickListener(AbsPublishNearFishingFragment.this);
			}
		}

		@Override
		public ImageHolder onCreateViewHolder(ViewGroup parent, int position) {
			View view = View.inflate(parent.getContext(), R.layout.image_item, null);
			return new ImageHolder(view);
		}

	}

	class ImageHolder extends RecyclerView.ViewHolder {
		private NetworkImageView mImageView;
		private ImageView mDeleteView;

		public ImageHolder(View itemView) {
			super(itemView);
			mImageView = (NetworkImageView) itemView.findViewById(R.id.image);
			registerForContextMenu(mImageView);
			mDeleteView = (ImageView) itemView.findViewById(R.id.delete);
			mDeleteView.setOnClickListener(AbsPublishNearFishingFragment.this);
		}

		public NetworkImageView getImageView() {
			return mImageView;
		}

		public ImageView getDeleteImageView() {
			return mDeleteView;
		}
	}
}
